package com.itclass.auth.handler.authentication.support;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.itclass.auth.authentication.token.supprt.UsernamePasswordLoginAuthenticationToken;
import com.itclass.auth.constant.AuthServerConstants;
import com.itclass.auth.constant.RedisCacheKeyConstants;
import com.itclass.auth.enums.AccountTypeEnum;
import com.itclass.auth.handler.authentication.AbstractAuthenticationFailureHandler;
import com.itclass.auth.pojo.db.SysUser;
import com.itclass.auth.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Component;

import java.util.Collections;


/**
 * 用户认证失败回调处理器 回调
 */
@Component
public class UsernamePasswordAuthenticationFailureHandler extends AbstractAuthenticationFailureHandler<UsernamePasswordLoginAuthenticationToken> {



    @Autowired
    private StringRedisTemplate stringRedisTemplate;



    @Autowired
    private SysUserService sysUserService;
    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordLoginAuthenticationToken.class.isAssignableFrom(authentication);
    }
    @Override
    public void handle(UsernamePasswordLoginAuthenticationToken authentication) {
        // 获取账号用户名
        String principal = (String) authentication.getPrincipal();

        // 失败次数 +1
        RedisScript<Long> script = new DefaultRedisScript<>(AuthServerConstants.incrScript, Long.class);
        Long incr = stringRedisTemplate.execute(script, Collections.singletonList(RedisCacheKeyConstants.LOGIN_FAILURE + principal), AuthServerConstants.LoginFailTime);        // 失败次数超过这个次数，该账号直接锁定不要登录
        // 超过失败次数，直接锁定账号，不让登录
        if (AuthServerConstants.LoginFailCount <= incr) {
            UpdateWrapper<SysUser> wrapper = new UpdateWrapper<>();
            wrapper.set("status",0);
            wrapper.eq("username",principal);
            wrapper.eq("type", AccountTypeEnum.SIMPL.getType());

            boolean update = sysUserService.update(wrapper);
        }

    }


}
